﻿using System;

namespace lbc_02_emulator
{
    public class CTrame
    {
        private string m_data, m_app, m_record, m_year, m_month, m_day,
            m_hour, m_minute, m_second, m_machineId, m_screen, m_checksum;
        private readonly string m_stx = ((char)2).ToString();
        private readonly string m_etx = ((char)3).ToString();

        DateTime temps;

        public string MachineID
        {
            set
            {
                if (value.Length == 1)
                    m_machineId = value;
            }
        }

        public string MachineModel
        {
            set
            {
                if (value.Length == 1)
                    m_app = value;
            }
        }

        public string Screen
        {
            set
            {
                if (value.Length == 1)
                    m_screen = value;
            }
        }

        // Un constucteur qui permet de changer l'heure et les minutes de la tramme
        public CTrame(string data, int record, string heure, string minute)
            : this(data, record)
        {
            m_hour = AddZero(heure);
            m_minute = AddZero(minute);
        }

        // Un constructeur avec 2 argument : le data a envoyé et l'identificateur de la tramme
        public CTrame(string data, int record)
        {
            m_data = data;
            temps = DateTime.Now;
            m_record = record.ToString();
            // On va initialiser nos variable temps
            FeedTime();

            // On ne peut plus le faire d'ici, mais doit être appelé dans le ToString()
            //// Calcul du checksum
            //m_checksum = CalculeCheckSum(m_data);

            // Le reste pourra être changé grâce aux propriété, sinon la valeur sera à 0 Convert
            m_app = "0";
        }

        // Convertit un entier en Hexa et le retourne sous forme de string
        private string ConvertToHexa(int Entier, int op)
        {
            string[,] HexaBin = {
                                 {"0", "1", "2", "3", "4", "5", "6", "7", "8", 
                                     "9", "A", "B", "C", "D", "E", "F"},
                                 {"0000", "0001", "0010", "0011",
                                     "0100", "0101", "0110", "0111",
                                     "1000", "1001", "1010", "1011",
                                     "1100", "1101", "1110", "1111"}
                             };
            // op : 1 = Hexa ---> Dec ; 2 = Dec ---> Hexa
            bool Check = true;
            string StringConverted, StringToCheck;
            StringConverted = StringToCheck = "";
            int index, StringLength, HexaDec, exposant;
            index = StringLength = HexaDec = 0;
            string value = Entier.ToString();

            if (op == 1)
            {
                value = value.Remove(0, 2);
                StringLength = value.Length;
                exposant = 0;
                for (int i = StringLength - 1; i >= 0; i--)
                {
                    StringToCheck = value[i].ToString();

                    index = 0;
                    Check = true;
                    while (Check)
                    {
                        if (String.Compare(StringToCheck, HexaBin[0, index]) == 0)
                        {
                            HexaDec += index * (int)Math.Pow(16.0, exposant);
                            Check = false;
                        }
                        index++;
                    }
                    exposant++;
                }
                StringConverted = HexaDec.ToString();
            }
            else
            {
                HexaDec = Entier;
                
                while (HexaDec != 0)
                {
                    StringConverted = HexaBin[0, HexaDec % 16] + StringConverted;
                    HexaDec = HexaDec / 16;
                }
                //StringConverted = "0x" + StringConverted;
            }
            return StringConverted; 
        }

        // Calcule le checksum du data et le retourne sous forme de string
        private string CalculeCheckSum(string data)
        {
            string retour = "";
            //string onTest = ((char)2) + "=B100112121580              01,1                                       ,";
            //data = onTest;
            int somme = 0;

            for (int i = 0; i < data.Length; i++)
            {
                somme += Convert.ToInt32(data[i]);
            }

            // On passe l'entier somme et le transforme en Hexa et reviens sous la forme d'un string
            retour = ConvertToHexa(somme, 2);

            // On garde que les deux derniers chiffres
            retour = retour.Remove(0,retour.Length - 2);
            //System.Windows.Forms.MessageBox.Show(retour);

            return retour;
        }


        // Ajoute un zero à gauche si le chiffre est seule
        private string AddZero(string zero)
        {
            string retour = zero;
            if (retour.Length < 2)
                retour = "0" + retour;
            return retour;
        }

        // Garnis nos variable temps;
        private void FeedTime()
        {
            m_year = temps.Year.ToString().Remove(0,2);
            m_month = AddZero(temps.Month.ToString());
            m_day = AddZero(temps.Day.ToString());
            m_hour = AddZero(temps.Hour.ToString());
            m_minute = AddZero(temps.Minute.ToString());
            m_second = AddZero(temps.Second.ToString());
        }

        override public string ToString()
        {
            string trammeToString = "";

            // on va construire la chaine ici avant de la passer en byte
            // Première pass, sans caractère stx etx et le checksum
            trammeToString += m_stx + m_record + m_app + m_month + m_day + m_year
                + m_hour + m_minute + m_second + m_machineId + m_screen + "," + m_data + ",";
            //string onTest = ((char)2) + "=B100112121580              01,2                                       " + ((char)3);
            //trammeToString = onTest;
            m_checksum = CalculeCheckSum(trammeToString);
            trammeToString = trammeToString + m_checksum + m_etx;
            //System.Windows.Forms.MessageBox.Show(trammeToString);
            return trammeToString;
        }

        public byte[] GetByte()
        {
            string Tramme = this.ToString();
            int longueur = Tramme.Length;
            byte[] chaine = new byte[longueur];

            chaine = System.Text.Encoding.GetEncoding(437).GetBytes(Tramme);
            return chaine;
        }
    }
}